home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / text / hyper / hsc_source.lha / hsc / source / ugly / fname.c < prev    next >
C/C++ Source or Header  |  1996-11-12  |  12KB  |  501 lines

  1. /*
  2.  * fname.c
  3.  *
  4.  * filename processing functions
  5.  *
  6.  * Copyright (C) 1994,95,96  Thomas Aglassinger
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * updated: 27-Oct-1996
  23.  * created: 24-May-1994
  24.  *
  25.  *-------------------------------------------------------------------
  26.  *
  27.  */
  28.  
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32.  
  33. #include "utypes.h"
  34. #include "umemory.h"
  35. #include "ustring.h"
  36. #include "expstr.h"
  37.  
  38. #define NOEXTERN_UGLY_FNAME_H
  39. #include "fname.h"
  40.  
  41. /*
  42.  * get_fext
  43.  *
  44.  * get filename extension
  45.  *
  46.  * params: fn...full filename to examine
  47.  * result: extension of _fn or NULL, if fn was also NULL
  48.  *
  49.  */
  50. BOOL get_fext(EXPSTR * dest, CONSTRPTR fn)
  51. {
  52.     CONSTRPTR fn_ext = fn;      /* result var */
  53.  
  54.     /* search for end of string */
  55.     while (fn_ext[0])
  56.         fn_ext++;
  57.  
  58.     /* search string backwards for "." or PATH_SEPARATOR */
  59.     do
  60.         /* nufin */ ;
  61.     while ((fn_ext != fn)       /* beginning of name reached? */
  62.            && (fn_ext--)        /* process next char */
  63.            && (fn_ext[0] != '.')
  64.            && (strchr(PATH_SEPARATOR, fn_ext[0]) == NULL));
  65.  
  66.     /* copy extension to dest */
  67.     if (fn_ext[0] == '.')
  68.         set_estr(dest, ++fn_ext);
  69.     else
  70.         clr_estr(dest);
  71.  
  72.     return (ok_fnl_fext(dest));
  73. }
  74.  
  75. /*
  76.  * get_fname
  77.  *
  78.  *
  79.  */
  80. BOOL get_fname(EXPSTR * dest, CONSTRPTR fn)
  81. {
  82.     CONSTRPTR fn_name = fn;
  83.  
  84.     fn_name = ustrrpbrk(fn_name, PATH_SEPARATOR);
  85.  
  86.     /* copy extension to dest */
  87.     if (fn_name)
  88.         set_estr(dest, ++fn_name);
  89.     else
  90.         set_estr(dest, fn);
  91.  
  92.     return (ok_fnl_fname(dest));
  93. }
  94.  
  95. /*
  96.  * get_fpath
  97.  *
  98.  *
  99.  */
  100. BOOL get_fpath(EXPSTR * dest, CONSTRPTR fn)
  101. {
  102.     STRPTR pa_name = ustrrpbrk(fn, PATH_SEPARATOR);
  103.  
  104.     if (pa_name)
  105.     {
  106.         set_estrn(dest, fn, strlen(fn) - strlen(pa_name) + 1);
  107.     }
  108.     else
  109.         clr_estr(dest);
  110.  
  111.     return (ok_fnl_fpath(dest));
  112. }
  113.  
  114. /*
  115.  * get_fsdir: get next subdirectory (including separator)
  116.  *
  117.  */
  118. BOOL get_fsdir(EXPSTR * dest, CONSTRPTR fn)
  119. {
  120.     STRPTR fn_name = strpbrk(fn, PATH_SEPARATOR);
  121.  
  122.     if (fn_name)
  123.     {
  124.         set_estrn(dest, fn, strlen(fn) - strlen(fn_name) + 1);
  125.     }
  126.     else
  127.         clr_estr(dest);
  128.  
  129.     return (ok_fnl_fpath(dest));
  130. }
  131.  
  132. /*
  133.  * get_fdrive
  134.  *
  135.  *
  136.  */
  137. BOOL get_fdrive(EXPSTR * dest, CONSTRPTR fn)
  138. {
  139.     set_estr(dest, fn);         /* dummy data */
  140.     clr_estr(dest);
  141.     return (ok_fnl_fpath(dest));
  142. }
  143.  
  144. /*
  145.  * fextidx: get filename extension index of string
  146.  *
  147.  * params: fn...filename to examine
  148.  * result: index in _fn, where extension starts
  149.  *
  150.  * NOTE: if _fn has an extension at all, _fn[i] is equal to '.', else
  151.  *       _fn has no extension (e.g. "TESTFILE") and _fn[i] is equal
  152.  *       to '\0'.
  153.  *
  154.  * (internal function)
  155.  *
  156.  */
  157. static size_t fextidx(CONSTRPTR fn)
  158. {
  159.     size_t i;                   /* string index counter */
  160.  
  161.     i = strlen(fn) - 1;         /* scan string backwards... */
  162.     while ((i) && (fn[i] != '.')
  163.            && (strchr(PATH_SEPARATOR, fn[i]) == NULL))
  164.         i--;
  165.     if (fn[i] != '.')
  166.         i = strlen(fn);
  167.  
  168.     return i;                   /* return result */
  169. }
  170.  
  171. /*
  172.  * clr_fext: clear filename extension
  173.  *
  174.  * params: dest...string that contains filename to strip
  175.  *
  176.  * EXAMPLE: "testfile.txt" -> "testfile"
  177.  *
  178.  */
  179. BOOL clr_fext(EXPSTR * dest)
  180. {
  181.     BOOL ok;
  182.     size_t extidx = fextidx(estr2str(dest));
  183.     /* index, where extension starts */
  184.     ok = set_estrn(dest, estr2str(dest), extidx);
  185.     ok &= ok_fnl_fpath(dest);
  186.  
  187.     return (ok);
  188. }
  189.  
  190. /*
  191.  * set_fext: set new (last) extension for filename
  192.  *
  193.  * params: dest....string that contains old filename
  194.  *         newext..new extension to set
  195.  *
  196.  * EXAMPLE: "testfile.txt", "lha" -> "testfile.lha"
  197.  *          "hugo.tar.gz" , "lha" -> "hugo.tar.lha"
  198.  */
  199. BOOL set_fext(EXPSTR * dest, CONSTRPTR newext)
  200. {
  201.     BOOL ok;
  202.  
  203.     ok = clr_fext(dest);
  204.     ok &= app_estrch(dest, '.');
  205.     ok &= app_estr(dest, newext);
  206.  
  207.     ok &= ok_fnl_fpath(dest);
  208.  
  209.     return (ok);
  210. }
  211.  
  212. /*
  213.  * app_fext: append extension to filename
  214.  *
  215.  * EXAMPLE: ("testfile.txt", "lha") -> "testfile.txt.lha"
  216.  *                                  -> "testfile.lha"     (msdos)
  217.  */
  218. BOOL app_fext(EXPSTR * dest, CONSTRPTR newext)
  219. {
  220.     BOOL ok = app_estrch(dest, '.');
  221.  
  222.     ok &= app_estr(dest, newext);
  223.     ok &= ok_fnl_fpath(dest);
  224.  
  225.     return (ok);
  226. }
  227.  
  228. /*
  229.  * set_fextIdx: set file name index extension
  230.  *
  231.  * params: dest..destination string with new extension
  232.  *         fn....source string with extension to replace
  233.  *         idx...extension index
  234.  */
  235. BOOL set_fnameIdx(EXPSTR * dest, int idx)
  236. {
  237.     char fn_ext[12];            /* index extension */
  238.     sprintf(fn_ext, "%03d", idx);       /* create index string */
  239.  
  240.     return (set_fext(dest, fn_ext));
  241. }
  242.  
  243. /*
  244.  * link_fname: link directory and filename together
  245.  *
  246.  * params: dest..where to store result
  247.  *         dir...directoryname
  248.  *         fn....filename to append
  249.  *
  250.  * NOTE: a PATHSEPARATOR[0] is append to dir, if none exists
  251.  * NOTE: dir and fn MUST NOT be part of dest,
  252.  *       when invoking this funtion
  253.  */
  254. BOOL link_fname(EXPSTR * dest, STRPTR dir, STRPTR fn)
  255. {
  256.     BOOL anydir;                /* TRUE, if any dir passed as arg */
  257.     BOOL ok = TRUE;
  258.  
  259.     /* is a dir passed? */
  260.     anydir = (dir != NULL);
  261.     if (anydir)
  262.         anydir = (strlen(dir) != 0);
  263.  
  264.     if (anydir)
  265.     {
  266.         /* clone dir, if any
  267.          *
  268.          * NOTE: it's neccesarry to work with a copy do `dir',
  269.          * because if `dir' is part or `dest', this could lead
  270.          * to a mungwall hit */
  271.         STRPTR dir_clone = strclone(dir);       /* clone of `dir' */
  272.  
  273.         set_estr(dest, dir_clone);
  274.         /* check, if the last char of dir is a path separator */
  275.         /* ->if not, append a direcory separator */
  276.         if (!strchr(PATH_SEPARATOR, dir_clone[strlen(dir_clone) - 1]))
  277.             app_estrch(dest, DIR_SEPARATOR);
  278.  
  279.         /* free cloned dir */
  280.         ufreestr(dir_clone);
  281.     }
  282.     else
  283.         clr_estr(dest);
  284.  
  285.     /* append filename */
  286.     if (fn)
  287.         app_estr(dest, fn);
  288.  
  289.     ok &= ok_fnl_fpath(dest);
  290.  
  291.     return ok;
  292. }
  293.  
  294. /*
  295.  * link_envfname: link content of an environment variable,
  296.  *                directory and filename together
  297.  *
  298.  * params: dest..where to store result
  299.  *         env...name of environment variable
  300.  *         dir...directoryname
  301.  *         fn....filename to append
  302.  *
  303.  * result: FALSE, if envvar could not be found or
  304.  *         filename got too long
  305.  */
  306. BOOL link_envfname(EXPSTR * dest, STRPTR envname, STRPTR dir, STRPTR fn)
  307. {
  308.     BOOL ok = FALSE;
  309.     STRPTR env = getenv(envname);
  310.  
  311.     if (env)
  312.     {
  313.         STRPTR env1 = strclone(env);        /* copy envvar to own memory area */
  314.         EXPSTR *tmpstr = init_estr(32);
  315.  
  316.         /* strip linefeeds from hscenv */
  317.         while (strlen(env1) && (env1[strlen(env1)] == '\n'))
  318.             env1[strlen(env1)] = '\0';
  319.  
  320.         if (dir)
  321.         {
  322.             link_fname(tmpstr, env1, dir);
  323.         }
  324.         else
  325.         {
  326.             set_estr(tmpstr, env1);
  327.         }
  328.  
  329.         ok = link_fname(dest, estr2str(tmpstr), fn);
  330.  
  331.         del_estr(tmpstr);
  332.         ufreestr(env1);
  333.     }
  334.     else
  335.     {
  336.         clr_estr(dest);
  337.     }
  338.  
  339.     return ok;
  340. }
  341.  
  342. /*
  343.  * tmpnamstr: alloc & create a string with a temp. filename
  344.  *
  345.  * result: string containig filename;
  346.  *         MUST be release using ufreestr() by caller
  347.  * errors: return NULL; this can be because auf no more
  348.  *         temp. files available or out of mem
  349.  *
  350.  * IMPORTANT: you need to copy the filename, if you
  351.  *           call this function frquently
  352.  */
  353. static size_t adjust_prefixlen(size_t prefixlen)
  354. {
  355. #ifdef MSDOS
  356.     if (prefixlen > MAX_FNAME - 4)
  357.         prefixlen = MAX_FNAME - 4;
  358. #else
  359.     if (prefixlen > MAX_FNAME - 8)
  360.         prefixlen = MAX_FNAME - 8;
  361. #endif
  362.  
  363.     return (prefixlen);
  364. }
  365.  
  366. STRPTR tmpnamstr(STRPTR prefix)
  367. {
  368.     STRARR buf[256 + 32];
  369.     LONG fileidx = 0;
  370.     STRPTR s = NULL;
  371.     FILE *file = NULL;
  372.     size_t prefixlen = 0;
  373.  
  374.     if (prefix)
  375.         /* copy prefix to buffer */
  376.         prefixlen = adjust_prefixlen(strlen(prefix));
  377.     else
  378.         prefix = "";
  379.  
  380.     /* copy prefix to buffer */
  381.     strcpy(buf, prefix);
  382.  
  383.     /* add address of buffer to prefix */
  384.     sprintf(&(buf[strlen(prefix)]), "%p", tmpnamstr);
  385.  
  386.     prefixlen = adjust_prefixlen(strlen(buf));
  387.     buf[prefixlen] = '\0';
  388.  
  389.     /* try to open tmpfile for input until it fails */
  390.     do
  391.     {
  392.         fileidx++;
  393.         sprintf(&(buf[prefixlen]), "%04lx", fileidx);
  394.         strcat(buf, ".tmp");
  395.         file = fopen(buf, "r");
  396.         if (file)
  397.         {
  398.             if (fileidx == 0xffff)
  399.                 fileidx = 0;    /* ran out of names */
  400.         }
  401.     }
  402.     while (fileidx && file);
  403.  
  404.     if (fileidx)
  405.     {
  406.         s = buf;
  407.     }
  408.  
  409.     return (s);
  410. }
  411.  
  412. /*
  413.  * get_relfname: get relative filename, according to given path
  414.  *
  415.  * params: absn..absolute filename
  416.  *         curp..current path
  417.  *
  418.  * EXAMPLE:
  419.  *  "image/back.gif" and "image/hugo/" -> "/back.gif"
  420.  *  "image/back.gif" and ""            -> "image/back.gif"
  421.  *  "image/back.gif" and "people/"     -> "/image/back.gif"
  422.  */
  423. BOOL get_relfname(EXPSTR * dest, STRPTR absn, STRPTR curp)
  424. {
  425.     EXPSTR *fname = init_estr(32);      /* file name only */
  426.     EXPSTR *abspa = init_estr(32);      /* absolute path only */
  427.     EXPSTR *tmpp1 = init_estr(32);      /* temp pointer */
  428.     EXPSTR *tmpp2 = init_estr(32);
  429.     STRPTR rest_absp = NULL;    /* rest of current path */
  430.     STRPTR absp = NULL;         /* path processing */
  431.     int cmp_result;             /* stores result returned by upstrcmp */
  432.  
  433.     /* init string array */
  434.     clr_estr(dest);
  435.     get_fname(fname, absn);
  436.     get_fpath(abspa, absn);
  437.     absp = estr2str(abspa);
  438.  
  439.     /*
  440.      * skip all equal subdirs
  441.      */
  442.     do
  443.     {
  444.         get_fsdir(tmpp1, absp);
  445.         get_fsdir(tmpp2, curp);
  446.         cmp_result = upstrcmp(estr2str(tmpp1), estr2str(tmpp2));
  447.  
  448.         if (!cmp_result)
  449.         {
  450.             absp += estrlen(tmpp1);
  451.             curp += estrlen(tmpp2);
  452.         }
  453.     }
  454.     while (estrlen(tmpp1)
  455.            && estrlen(tmpp2)
  456.            && (!cmp_result));
  457.  
  458.     /* remember equal part of path */
  459.     rest_absp = absp;
  460.  
  461.     /*
  462.      * for every subdir in absp unequal to
  463.      * corresponding subdir curp, insert a parent dir
  464.      */
  465.     if (curp[0])
  466.         do
  467.         {
  468.             get_fsdir(tmpp1, absp);
  469.             get_fsdir(tmpp2, curp);
  470.             cmp_result = upstrcmp(estr2str(tmpp1), estr2str(tmpp2));
  471.  
  472.             if (cmp_result)
  473.             {
  474.                 absp += estrlen(tmpp1);
  475.                 curp += estrlen(tmpp2);
  476.                 app_estr(dest, PARENT_DIR);
  477. #if 0
  478.                 printf("absp: (tmpp1) [%d] `%s'\n", estrlen(tmpp1), absp);
  479.                 printf("curp: (tmpp2) [%d] `%s'\n", estrlen(tmpp2), curp);
  480.                 printf("dest: `%s'\n", estr2str(dest));
  481. #endif
  482.             }
  483.         }
  484.         while (strlen(curp) && cmp_result);
  485.  
  486.     /* append equal part of path */
  487.     app_estr(dest, rest_absp);
  488.  
  489.     /* append name of file */
  490.     app_estr(dest, estr2str(fname));
  491.  
  492.     /* relaese resources */
  493.     del_estr(fname);
  494.     del_estr(abspa);
  495.     del_estr(tmpp1);
  496.     del_estr(tmpp2);
  497.  
  498.     return (ok_fnl_fpath(dest));
  499. }
  500.  
  501.